/* 
 * Copyright (c) 2009-2012, Newcastle University, UK.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met: 
 * 1. Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE. 
 *
 * KL 21-10-2011
 * Hardware profile for TEDDI1.0
 */
 
#ifndef HARDWAREPROFILE_TEDDI_H
#define HARDWAREPROFILE_TEDDI_H

#include "GenericTypeDefs.h"
#include "ConfigApp.h"

// no such thing on pic24
#define far

// Super Essential Defines / Pre-compiler stuff
#define USE_AND_OR /* To enable AND_OR mask setting */

// System tick - presently the sample tick
#define T1_ISR_RATE 100 /*for 100 Hz*/

//SystemPwrSave arguments OR together
#define WAKE_ON_USB		1
#define WAKE_ON_BUTTON	32
#define WAKE_ON_WDT		64
#define WAKE_ON_RTC		128
#define WAKE_ON_TIMER1	256
#define LOWER_PWR_SLOWER_WAKE	512
#define ADC_POWER_DOWN			1024
#define SAVE_INT_STATUS			16384
#define ALLOW_VECTOR_ON_WAKE	32768
#define LEAVE_WDT_RUNNING		65536
#define JUST_POWER_DOWN_PERIPHERALS	131072
#define DONT_RESTORE_PERIPHERALS	262144

// LED colour enum
enum COLOUR{
ColourOff,	
ColourRed,	
ColourGreen,	
ColourYellow,	
ColourBlue,	
ColourMagenta,	
ColourCyan,
ColourWhite	
};

// Essential Functions in HardwareProfile.c
extern void LEDColour (enum COLOUR);// colour);
extern void WaitForPrecharge(void);
extern void SystemPwrSave(unsigned long NapSetting);

#define 	PIC24
#define 	CWA2

	// Used for delays in TimeDelay.h
	#define GetInstructionClock()  4000000

    // USB bus sense I/O
    // #define USE_USB_BUS_SENSE_IO
    #define USB_BUS_SENSE_PIN   TRISCbits.TRISC6
    #define USB_BUS_SENSE       PORTCbits.RC6
	#define USB_BUS_SENSE_INIT() USB_BUS_SENSE_PIN=1
	// Int1 fires on USB detect
	#define SetupUSBsenseInts()	{INTCON2bits.INT1EP=0;IFS1bits.INT1IF=0;IEC1bits.INT1IE=1;}

	// Button
	#define INIT_BUTTON_PINS()	{TRISBbits.TRISB7 = 1;}
	#define INIT_BUTTON_INT()	{/*Int on change- CN23*/\					
									CNEN2bits.CN23IE = 1;\
									IFS1bits.CNIF = 0;/*Flag*/\
									IEC1bits.CNIE = 1;/*Unmask*/\
									IPC4bits.CNIP = 4;/*Priority*/}
    
    #define PUSH_BUTTON_1       PORTBbits.RB7
    #define PUSH_BUTTON_2       PUSH_BUTTON_1

	// The pins
	#define InitIO(){\
					REMAP_PINS();\
					USB_BUS_SENSE_INIT();\
					INIT_BUTTON_PINS();\
					LED_INIT_PINS();\
					TEMP_INIT_PINS();\
					LDR_INIT_PINS();\
					ADC_INIT_PINS();\
					RF_INIT_PINS();\
					ANALOGUE_INIT_PINS();\
					INIT_POWER_CTRL_PINS_OFF();\
					UART_INIT();\
					DriveFloatingPins(); /*Reduce leakage*/\
					}		

	#define DriveFloatingPins() {\
								/*This HW has no spare pins!*/\
								}
	
	// Power control pins
	#define AUDIO_POWER_PIN	TRISAbits.TRISA10
	#define nAUDIO_POWER	LATAbits.LATA10
	#define MRF_POWER_PIN	TRISAbits.TRISA9
	#define nMRF_POWER		LATAbits.LATA9
	#define PIR_POWER_PIN	TRISCbits.TRISC1
	#define nPIR_POWER		LATCbits.LATC1
	#define INIT_POWER_CTRL_PINS_OFF()	{\
										AUDIO_POWER_PIN	= 0;\
										nAUDIO_POWER	= 1;\
										MRF_POWER_PIN	= 0;\
										nMRF_POWER		= 1;\
										PIR_POWER_PIN 	= 0;\
										nPIR_POWER		= 1;\
										}								
										
	// UART
	/*	The uart is supported by a FTDI USB chip, the tracks must be cut and the 
		chip soldered in to allow this functionality. #include <uart.h> 
		UxBRG = ((Fcy/Baud)/16)-1, 4MIPS, 57600->16.36*/
	#define UART_RX_PIN	TRISBbits.TRISB10
	#define UART_TX_PIN	TRISBbits.TRISB11
	#define UART_INIT()	{UART_RX_PIN=1;\
						UART_TX_PIN=0;\
						OpenUART1 (\
						/*U1MODEvalue*/\
						(UART_EN|\
						UART_IDLE_STOP|\
						UART_IrDA_DISABLE|\
						UART_MODE_SIMPLEX|\
						UART_UEN_00|\
						UART_DIS_WAKE|\
						UART_DIS_LOOPBACK|\
						UART_DIS_ABAUD|\
						UART_BRGH_FOUR|\
						UART_NO_PAR_8BIT|\
						UART_1STOPBIT),\
						/*U1STAvalue*/\
						UART_INT_TX_BUF_EMPTY|\
						UART_TX_ENABLE|\
						UART_INT_RX_CHAR|\
						UART_ADR_DETECT_DIS|\
						UART_RX_OVERRUN_CLEAR|\
						UART_IrDA_POL_INV_ZERO|\
						UART_SYNC_BREAK_DISABLED,\
						/*baud*/\
						16);}
						
	// REMAP pins
	#define REMAP_PINS()		{\
							__builtin_write_OSCCONL(OSCCON & 0xBF);/*Unlock*/\
							/* NB, Bug on schematic, int1 and int2 on adxl not labeled correctly*/\
							/* therefore HW profile does not reflect schematic exactly*/\
							RPINR0bits.INT1R = 22;/* RP22/USB_BUS_SENSE -> Int1 */\
							RPINR1bits.INT2R = 21;/* RP21/MINT -> Int2 */\
							RPINR20bits.SCK1R= 18;/* MSCK RP13 -> SCK1i */\
							RPINR20bits.SDI1R= 9;/* MSDO RP7 -> SDI1 */\
							RPOR4bits.RP9R = 18;  /* MSCK RP13 -> SCK1o */\
							RPOR3bits.RP6R = 7;  /* MSDI RP6 -> SDO1 */\
							RPINR22bits.SCK2R= 14;/* ADCSCK RP13 -> SCK1i */\
							RPINR22bits.SDI2R= 15;/* ADCSDO RP7 -> SDI1 */\
							RPOR7bits.RP14R = 11;  /* ADCSCK RP13 -> SCK1o */\
							RPINR18bits.U1RXR = 10;/*UART1 RX to RP10/D+*/\
							RPOR5bits.RP11R = 3;/*UART1 TX to RP11/D-*/\
							/*Then lock the PPS module*/\
							__builtin_write_OSCCONL(OSCCON | 0x40);\
							}						

    // Clock: initialize PLL for 96 MHz USB and 12MIPS
	#define CLOCK_PLL() 	{\
							OSCCONBITS OSCCONBITS_copy = OSCCONbits;\
							asm("DISI #0x3FFF");\
							OSCCONBITS_copy.NOSC = 0b001;			/*Internal FRC+PLL oscillator*/\
							OSCCONBITS_copy.OSWEN = 1;\
							__builtin_write_OSCCONH( ((unsigned char*)  &OSCCONBITS_copy)[1] );\
							__builtin_write_OSCCONL( ((unsigned char*)  &OSCCONBITS_copy)[0] );\
							asm("DISI #0");\
							while (OSCCONbits.OSWEN == 1);\
							while (OSCCONbits.LOCK != 1); 			/*Wait for PLL lock to engage*/\
							CLKDIVbits.RCDIV = 0b000; 				/*8 MHz */\
							}				

    // Clock: switch to 8 MHz INTOSC
	#define CLOCK_INTOSC() 	{\
							OSCCONBITS OSCCONBITS_copy = OSCCONbits;\
							asm("DISI #0x3FFF");\
							OSCCONBITS_copy.NOSC = 0b111;			/*Internal FRC oscillator*/\
							OSCCONBITS_copy.OSWEN = 1;\
							__builtin_write_OSCCONH( ((unsigned char*)  &OSCCONBITS_copy)[1] );\
							__builtin_write_OSCCONL( ((unsigned char*)  &OSCCONBITS_copy)[0] );\
							asm("DISI #0");\
							while (OSCCONbits.OSWEN == 1);\
							CLKDIVbits.RCDIV = 0b000; 				/*8 MHz */\
							}

    // Clock: switch to 31 kHz INTRC
    #define CLOCK_INTRC() 	{\
							OSCCONBITS OSCCONBITS_copy = OSCCONbits;\
							asm("DISI #0x3FFF");\
							OSCCONBITS_copy.NOSC = 0b101;			/*Internal RC oscillator*/\
							OSCCONBITS_copy.OSWEN = 1;\
							__builtin_write_OSCCONH( ((unsigned char*)  &OSCCONBITS_copy)[1] );\
							__builtin_write_OSCCONL( ((unsigned char*)  &OSCCONBITS_copy)[0] );\
							asm("DISI #0");\
							while (OSCCONbits.OSWEN == 1);\
							CLKDIVbits.RCDIV = 0b000; 				/*8 MHz */\
							}
    #define CLOCK_32KHZ() 	{\
							OSCCONBITS OSCCONBITS_copy = OSCCONbits;\
							asm("DISI #0x3FFF");\
							OSCCONBITS_copy.NOSC = 0b100;			/*External secondary oscillator*/\
							OSCCONBITS_copy.OSWEN = 1;\
							__builtin_write_OSCCONH( ((unsigned char*)  &OSCCONBITS_copy)[1] );\
							__builtin_write_OSCCONL( ((unsigned char*)  &OSCCONBITS_copy)[0] );\
							asm("DISI #0");\
							while (OSCCONbits.OSWEN == 1);\
							CLKDIVbits.RCDIV = 0b000; 				/*8 MHz */\
							}
       
	// Secondary oscillator on
	#define CLOCK_SOSCEN()	{OSCCONbits.SOSCEN=1;}

    // LED
    #define LED_G_PIN  			TRISCbits.TRISC9        
    #define LED_G               LATCbits.LATC9
    #define LED_R_PIN           TRISCbits.TRISC8
    #define LED_R              	LATCbits.LATC8 
    #define LED_B_PIN           TRISCbits.TRISC7
    #define LED_B     			LATCbits.LATC7
	#define LED 				LED_R          
    #define LED_INIT_PINS()     {TRISC&=0b1111110001111111;LATC&=0b1111110001111111;}

    // LED suspend/resume (for LDR)
    #define LED_SUSPEND()       { LED_R_PIN = 1; LED_G_PIN = 1; LED_B_PIN = 1; }
    #define LED_RESUME()        { LED_R_PIN = 0; LED_G_PIN = 0; LED_B_PIN = 0; }


    // Battery AN5/RB5
    #define BATT_MON_PIN        TRISBbits.TRISB13
    #define BATT_INIT_PINS()   	BATT_MON_PIN = 1
	// 5% battery level - avoids unwanted RTC resets and file corruptions etc
	#define MINIMUM_SAFE_BATTERY_RUNNING_VOLTAGE 520
	
    
    // LDR AN13/RB13
    #define LDR_EN_PIN			TRISCbits.TRISC4         
    #define LDR_EN              LATCbits.LATC4
    #define LDR_OUT_PIN         TRISCbits.TRISC3
    #define LDR_ENABLE()        {LDR_OUT_PIN=1;LDR_EN_PIN = 0;LDR_EN = 0;}
    #define LDR_DISABLE()       {LDR_OUT_PIN=1;LDR_EN_PIN = 0;LDR_EN = 1;}
    #define LDR_INIT_PINS()     LDR_DISABLE()

	// Temp sensor
	#define USE_MCP9701
	#define TEMP_EN_PIN			TRISBbits.TRISB3
	#define TEMP_EN				LATBbits.LATB3
	#define TEMP_OUT_PIN		TRISBbits.TRISB2
	#define TEMP_ENABLE()		{TEMP_OUT_PIN=1;TEMP_EN_PIN=0;TEMP_EN=1;}
	#define TEMP_DISABLE()		{TEMP_OUT_PIN=1;TEMP_EN_PIN=0;TEMP_EN=0;}
	#define TEMP_INIT_PINS()	TEMP_DISABLE()

	// Analogue select pins - 0 = Analogue, Vref=Ana' too!
	#define ANALOGUE_SELECT_L 0b1110011110101100
	#define ANALOGUE_INIT_PINS()	{AD1PCFGL = ANALOGUE_SELECT_L;}

	// RTC
	// (Private) Convert a value from BCD - do not use this macro where evaluating the parameter has a side effect (e.g. a function call reading a value)
	//static unsigned char FromBcd(unsigned char value) { return ((value & 0xf0) >> 4) * 10 + (value & 0x0f); }
	#define FromBcd(_value) ((((_value) & 0xf0) >> 4) * 10 + ((_value) & 0x0f))   
	// (Private) Convert a value to BCD - do not use this macro where evaluating the parameter has a side effect (e.g. a function call reading a value)
	//static unsigned char ToBcd(unsigned char value) { return ((value / 10) << 4) | (value % 10); }
	#define ToBcd(_value) ((((_value) / 10) << 4) | ((_value) % 10))

 	// External 16bit ADC
	#define ADC_SDI_PIN		TRISBbits.TRISB15
	#define ADC_SCK_PIN		TRISBbits.TRISB14
	#define ADC_CS_PIN		TRISAbits.TRISA7
	#define ADC_CS			LATAbits.LATA7
	#define ADC_INIT_PINS()	 {\
								ADC_SDI_PIN = 1;\
								ADC_SCK_PIN = 0;\
								ADC_CS_PIN = 0;\
								ADC_CS = 0;\
								}						
	// MRF module
    #define TMRL                TMR1
    #define RFIF                IFS1bits.INT2IF
    #define RFIE                IEC1bits.INT2IE
    #define RF_IEDG  			INTCON2bits.INT2EP
    #define RF_INT_PIN          PORTCbits.RC5
    #define RF_INT_TRIS         TRISCbits.TRISC5
    #define PHY_CS              LATBbits.LATB5
    #define PHY_CS_TRIS         TRISBbits.TRISB5
    #define PHY_RESETn          LATAbits.LATA8
    #define PHY_RESETn_TRIS     TRISAbits.TRISA8
    #define PHY_WAKE            LATAbits.LATA3
    #define PHY_WAKE_TRIS       TRISAbits.TRISA3
    #define RF_USE_SPI          1
    #define RF_SPI_SI_TRIS      TRISBbits.TRISB9
    #define RF_SPI_SO_TRIS      TRISBbits.TRISB8
    #define RF_SPI_SCK_TRIS     TRISCbits.TRISC2

    #define RF_INIT_PINS()    {\
                                RF_SPI_SI_TRIS = 1;\
                                RF_SPI_SO_TRIS = 0;\
                                RF_SPI_SCK_TRIS = 0;\
                                PHY_CS = 1;\
                                PHY_CS_TRIS = 0;\
                                PHY_RESETn = 0;\
                                PHY_RESETn_TRIS = 0;\
                                PHY_WAKE = 1;\
                                PHY_WAKE_TRIS = 0;\
                                RFIF = 0;\
                                RF_INT_TRIS = 1;\
								RF_IEDG = 0;\
                                RFIE = 1;\
                            }
                            
//Miwi Stack integration stuff
   	#define CLOCK_FREQ 32000000
   	#define SPI_SDI             PORTBbits.RB9
    #define SDI_TRIS            RF_SPI_SI_TRIS
    #define SPI_SDO             LATBbits.LATB8 
    #define SDO_TRIS            RF_SPI_SO_TRIS
    #define SPI_SCK             LATCbits.LATC2 
    #define SCK_TRIS            RF_SPI_SCK_TRIS
   	


/* Call this to enable the SPI module
OpenSPI1(
(ENABLE_SCK_PIN |
ENABLE_SDO_PIN |
SPI_MODE8_ON |
SPI_SMP_OFF |
SPI_CKE_OFF |
CLK_POL_ACTIVE_LOW |
MASTER_ENABLE_ON |
SEC_PRESCAL_1_1 |
PRI_PRESCAL_4_1),
(FRAME_ENABLE_OFF |
FRAME_SYNC_OUTPUT |
FRAME_SYNC_ACTIVE_LOW |
SPI_FRM_PULSE_PREV_CLK |
SPI_ENH_BUFF_DISABLE ),
(SPI_ENABLE |
SPI_IDLE_STOP |
SPI_RX_OVFLOW_CLR ));}
*/
	
					

// Legacy includes for MCHIP stacks
 
    // USB (MCHPFSUSB framework)
    //#undef USE_SELF_POWER_SENSE_IO
    //#define tris_self_power     TRIS?bits.TRIS??    // Input
    //#define self_power          PORT?bits.R??
    #define self_power          0   // 0 = bus-powered, 1 = self-powered

	#define usb_bus_sense 		USB_BUS_SENSE

// Really unused stuff follows - just junk really


	#define mInitAllLEDs()      LED_INIT_PINS()
    
    #define mLED_1              LED_R
    #define mLED_2              LED_G
    #define mLED_3              LED_B
    #define mLED_4              LED_R

    #define mGetLED_1()         mLED_1
    #define mGetLED_2()         mLED_2
    #define mGetLED_3()         mLED_3
    #define mGetLED_4()         mLED_4     
    
    #define mLED_1_On()         mLED_1 = 1;
    #define mLED_2_On()         mLED_2 = 1;
    #define mLED_3_On()         mLED_3 = 1;
    #define mLED_4_On()         mLED_4 = 1;
    
    #define mLED_1_Off()        mLED_1 = 0;
    #define mLED_2_Off()        mLED_2 = 0;
    #define mLED_3_Off()        mLED_3 = 0;
    #define mLED_4_Off()        mLED_4 = 0;
    
    #define mLED_1_Toggle()     mLED_1 = !mLED_1;
    #define mLED_2_Toggle()     mLED_2 = !mLED_2;
    #define mLED_3_Toggle()     mLED_3 = !mLED_3;
    #define mLED_4_Toggle()     mLED_4 = !mLED_4;
    
    /** SWITCH *********************************************************/
    #define mInitSwitch2()      
    #define mInitSwitch3()      
    #define mInitAllSwitches()  

    /** I/O pin definitions ********************************************/
    #define INPUT_PIN 1
    #define OUTPUT_PIN 0



#endif
